/**
 * lilang
 * ProcessDefinitionServiceImpl.java
 * 2013-10-20下午4:54:56
 */
package com.cq.oa.service.work.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import oa.base.service.impl.BaseServiceImpl;
import oa.base.session.SessionManger;
import oa.base.util.BeanUtils;
import oa.base.util.Constants;

import com.cq.oa.dao.wfc.ActivityDao;
import com.cq.oa.dao.wfc.ActivityParticipationDao;
import com.cq.oa.dao.wfc.ProcessDefinitionDao;
import com.cq.oa.dao.wfc.ProcessJspDao;
import com.cq.oa.dao.wfc.ProcessTypeDao;
import com.cq.oa.dao.wfc.TransitionDao;
import com.cq.oa.domain.dto.WorkDto;
import com.cq.oa.domain.wfc.Activity;
import com.cq.oa.domain.wfc.ActivityParticipation;
import com.cq.oa.domain.wfc.ProcessDefinition;
import com.cq.oa.domain.wfc.Transition;
import com.cq.oa.service.work.ProcessDefinitionService;

/**
 * @author lilang
 *
 */
public class ProcessDefinitionServiceImpl extends BaseServiceImpl<ProcessDefinition> implements ProcessDefinitionService{
	
	private static final String DEFINITION_SID="processDefinitionSid";
	
	private static final String ACTIVITY_SID="activitySid";
	/**
	 * 缓存工作定义的数据
	 */
	public static Map<Long,WorkDto> loadDefinition = new HashMap<Long, WorkDto>();
	/**
	 * 最大缓存 流程
	 */
	public static int DEFINITION_SIZE=100;
	/**
	 * 流程定义
	 */
	private ProcessDefinitionDao processDefinitionDao;
	
	
	private ActivityDao activityDao;
	
	
	private TransitionDao transitionDao;
	
	
	private ActivityParticipationDao activityParticipationDao;
	
	private ProcessTypeDao processTypeDao;
	
	private ProcessJspDao processJspDao;


	public ProcessJspDao getProcessJspDao() {
		return processJspDao;
	}


	public void setProcessJspDao(ProcessJspDao processJspDao) {
		this.processJspDao = processJspDao;
	}


	public ProcessTypeDao getProcessTypeDao() {
		return processTypeDao;
	}


	public void setProcessTypeDao(ProcessTypeDao processTypeDao) {
		this.processTypeDao = processTypeDao;
	}


	public ProcessDefinitionDao getProcessDefinitionDao() {
		return processDefinitionDao;
	}


	public void setProcessDefinitionDao(ProcessDefinitionDao processDefinitionDao) {
		this.processDefinitionDao = processDefinitionDao;
	}


	public ActivityDao getActivityDao() {
		return activityDao;
	}


	public void setActivityDao(ActivityDao activityDao) {
		this.activityDao = activityDao;
	}


	public TransitionDao getTransitionDao() {
		return transitionDao;
	}


	public void setTransitionDao(TransitionDao transitionDao) {
		this.transitionDao = transitionDao;
	}


	public ActivityParticipationDao getActivityParticipationDao() {
		return activityParticipationDao;
	}


	public void setActivityParticipationDao(
			ActivityParticipationDao activityParticipationDao) {
		this.activityParticipationDao = activityParticipationDao;
	}


	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.ProcessDefinitionService#findProcessDefinitionById(java.lang.Long)
	 */
	public WorkDto findProcessDefinitionById(Long sid) {
		WorkDto dto = loadDefinition.get(sid);
		if(dto==null){
			ProcessDefinition processDefinition = this.processDefinitionDao.get(sid);
			Map<String,Object> params = new HashMap<String,Object>();
			params.put(DEFINITION_SID, sid);
			List<Activity> activities = this.activityDao.find(params);
			List<Transition> transitions =this.transitionDao.find(params);
			dto = new WorkDto();
			dto.setProcessDefinition(processDefinition);
			if(activities!=null&&activities.size()>0){
				dto.setActivities(activities);
				dto.setTransitions(transitions);
				dto.setActivityParticipations(this.findParticipation(activities));
				//设置属性
				dto.setPartiction();
				//如果 大于当前缓存 删除第一个
				if(loadDefinition.size()>=DEFINITION_SIZE){
					for(Long loadId:loadDefinition.keySet()){
						loadDefinition.remove(loadId);
						break;
					}
				}
				loadDefinition.put(sid, dto);
			}
		}
		return dto;
	}
	/**
	 * 查询活动条件
	 * @param activities
	 * @return
	 * lilang 
	 * 2013-10-25下午12:51:01
	 */
	public List<ActivityParticipation> findParticipation(List<Activity> activities){
		List<Long> sids = new ArrayList<Long>();
		for(Activity activity:activities){
			sids.add(activity.getSid());
		}
		Map<String,Object> params = new HashMap<String,Object>();
		params.put(Constants.WHERE_IN+ACTIVITY_SID, sids);
		return this.activityParticipationDao.find(params);
	}
	
	/**
	 * 查询活动条件
	 * @param activities
	 * @return
	 * lilang 
	 * 2013-10-25下午12:51:01
	 */
	public List<ActivityParticipation> findParticipation(Long  activityId){
		Map<String,Object> params = new HashMap<String,Object>();
		params.put(ACTIVITY_SID, activityId);
		return this.activityParticipationDao.find(params);
	}
	

	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.ProcessDefinitionService#doProcessDefinition(com.cq.oa.domain.dto.WorkDto)
	 */
	public void doProcessDefinition(ProcessDefinition definition) {
		if(definition.getSid()==null){
			this.processDefinitionDao.create(definition);
		}else{
			this.processDefinitionDao.update(definition);
		}
	}


	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.ProcessDefinitionService#doCopyProcessDefinition(java.lang.Long, java.lang.Long)
	 */
	public Long doCopyProcessDefinition(Long sid, Long orgId) {
		
		WorkDto dto = this.findProcessDefinitionById(sid);
		if(dto.getProcessDefinition()==null){
			return 0L;
		}
		//保存 流程定义
		ProcessDefinition definition = new ProcessDefinition();
		BeanUtils.copyProperties(dto.getProcessDefinition(), definition);
		definition.setSid(null);
		definition.setOrgSid(orgId);
		Long deId = this.processDefinitionDao.create(definition);
		//保存节点  ID
		Map<Long,Long> actMap = this.saveCopyActivity(dto.getActivities(), deId, orgId);
		//节点线
		this.saveCopyTransition(dto.getTransitions(), deId, orgId, actMap);
		//活动参与人
		this.saveCopyParticipation(dto.getActivityParticipations(), deId, orgId, actMap);
		return deId;
	}
	
	/**
	 * 保存copy 的节点 ID
	 * @return
	 * lilang 
	 * 2013-10-20下午8:10:41
	 */
	private Map<Long,Long> saveCopyActivity(List<Activity> activities,Long deId,Long orgId){
		Map<Long,Long> actMap = new HashMap<Long, Long>();
		List<Activity> list = new ArrayList<Activity>();
		for(Activity activity:activities){
			Activity act = new Activity();
			BeanUtils.copyProperties(activity, act);
			act.setOldId(act.getSid());
			this.activityDao.initBase(act);
			act.setSid(null);
			act.setProcessDefinitionSid(deId);
			act.setOrgSid(orgId);
			list.add(act);
		}
		this.activityDao.saveAll(list);
		for(Activity activity:list){
			actMap.put(activity.getOldId(), activity.getSid());
		}
		return actMap;
	}
	
	/**
	 * 保存copy 的路线信息
	 * @param transitions
	 * @param deId
	 * @param orgId
	 * @param actId
	 * lilang 
	 * 2013-10-20下午8:28:51
	 */
	private void saveCopyTransition(List<Transition> transitions,Long deId,Long orgId,Map<Long,Long> actId){
		List<Transition> list = new ArrayList<Transition>();
		for(Transition transition:transitions){
			Transition tran = new Transition();
			BeanUtils.copyProperties(transition, tran);
			tran.setSid(null);
			tran.setProcessDefinitionSid(deId);
			this.transitionDao.initBase(tran);
			tran.setFromSid(actId.get(transition.getFromSid()));
			tran.setToSid(actId.get(transition.getToSid()));
			tran.setOrgSid(orgId);
			list.add(tran);
		}
		this.transitionDao.saveAll(list);
	}
	
	/**
	 * 保存copy 的路线信息
	 * @param transitions
	 * @param deId
	 * @param orgId
	 * @param actId
	 * lilang 
	 * 2013-10-20下午8:28:51
	 */
	private void saveCopyParticipation(List<ActivityParticipation> activityParticipations,Long deId,Long orgId,Map<Long,Long> actId){
		List<ActivityParticipation> list = new ArrayList<ActivityParticipation>();
		for(ActivityParticipation participartion:activityParticipations){
			ActivityParticipation part = new ActivityParticipation();
			BeanUtils.copyProperties(participartion, part);
			part.setSid(null);
			part.setProcessDefinitionSid(deId);
			this.activityParticipationDao.initBase(part);
			part.setOrgSid(orgId);
			part.setActivitySid(actId.get(part.getActivitySid()));
			list.add(part);
		}
		this.activityParticipationDao.saveAll(activityParticipations);
	}


	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.ProcessDefinitionService#doActivityDefinition(com.cq.oa.domain.dto.WorkDto)
	 */
	public void doActivityDefinition(WorkDto dto) {
		Long orgId = SessionManger.getOrgId();
		Map<String,Object> param = new HashMap<String, Object>();
		param.put("processDefinitionSid", dto.getSid());
		this.activityDao.remove(param);
		this.activityParticipationDao.remove(param);
		this.transitionDao.remove(param);
		Map<Long,Long> actMap = this.saveCopyActivity(dto.getActivities(), dto.getSid(), orgId);
		this.saveCopyTransition(dto.getTransitions(),  dto.getSid(), orgId, actMap);
		this.saveCopyParticipation(dto.getActivityParticipations(), dto.getSid(), orgId, actMap);
	}


	/* (non-Javadoc)
	 * @see com.cq.oa.service.work.ProcessDefinitionService#findActivityPartion(java.lang.Long)
	 */
	public List<ActivityParticipation> findActivityPartion(Long activityId) {
		return this.findActivityPartion(activityId);
	}
	
	
	
	
}
